home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / packet / ax25ip.shr < prev    next >
Text File  |  1996-06-25  |  46KB  |  1,831 lines

  1. [ This device driver for the SunOS kernel allows the kernel network
  2.   layer to send IP packet inside AX25 (using a TNC on a serial port),
  3.   exactly like KA9Q NOS does.
  4.   The AX25 device appears exactly (ok, minus possible bugs :-) like
  5.   any other network device does to the kernel, so you can use any old
  6.   regular SunOS TCP/IP programs (ftp, telnet, etc). (Tested on Sun3/60
  7.   and Sun4/260, SunOS4.1.1.)
  8.   VERSION 1.0 deraadt@lego.cuc.ab.ca ]
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of shell archive."
  17. # Contents:  Makefile README ax25.8 ax25.c ax25ether.c if_ax.h tty_ax.c
  18. # Wrapped by deraadt@cpsc.UCalgary.CA on Sat Jan 25 02:48:06 1992
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'Makefile'\"
  22. else
  23. echo shar: Extracting \"'Makefile'\" \(73 characters\)
  24. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  25. XCFLAGS=    -g
  26. XBIN=    ax25ether ax25
  27. X
  28. Xall:    $(BIN)
  29. X
  30. Xclean:
  31. X    $(RM) *.o *~ $(BIN)
  32. END_OF_FILE
  33. if test 73 -ne `wc -c <'Makefile'`; then
  34.     echo shar: \"'Makefile'\" unpacked with wrong size!
  35. fi
  36. # end of 'Makefile'
  37. fi
  38. if test -f 'README' -a "${1}" != "-c" ; then 
  39.   echo shar: Will not clobber existing file \"'README'\"
  40. else
  41. echo shar: Extracting \"'README'\" \(3792 characters\)
  42. sed "s/^X//" >'README' <<'END_OF_FILE'
  43. XSTATUS:
  44. XTested on a Sun3/60 and a Sun4/260 running SunOS4.1.1, using a PacComm
  45. XTiny-2 TNC, and talking with other NOS sites in Calgary, Alberta.
  46. X
  47. XINSTALL:
  48. X0. Substitute the name 'KERNEL_CONFIG_FILE' in the following steps with the
  49. X   kernel configuration file for your new kernel (If in doubt, make a copy
  50. X   of GENERIC, and use it).
  51. X   Also, substitute 'sun3' with whatever the command 'arch -k' says
  52. X   your kernel architecture is.
  53. X
  54. X1.  First, you need to add the device driver to the kernel. Add this line to
  55. X    /usr/sys/sun3/conf/KERNEL_CONFIG_FILE.
  56. X    pseudo-device   ax1             init ax_attach
  57. X              ^ this number determines how many TNCs you can hook up.
  58. X
  59. X2.  splice these sections in the appropriate (fairly obvious) places in
  60. X    /usr/sys/sun/str_conf.c
  61. X    #include "ax.h"
  62. X
  63. X    #if     NAX > 0
  64. X    extern struct streamtab axinfo;
  65. X    #endif
  66. X
  67. X    #if     NAX > 0
  68. X            { "ax25",       &axinfo },
  69. X    #endif
  70. X
  71. X3.  add this line to /usr/sys/conf.common/files.cmn
  72. X    os/tty_ax.c             optional ax
  73. X
  74. X4.  Install the needed files in the kernel sys tree
  75. X    # cp tty_ax.c /usr/sys/os
  76. X    # cp if_ax.h /usr/include/sys
  77. X    # cp if_ax.h /usr/sys/sys
  78. X
  79. X5.  Build the kernel
  80. X    # cd /usr/sys/sun3/conf
  81. X    # config KERNEL_CONFIG_FILE
  82. X    # cd ../KERNEL_CONFIG_FILE
  83. X    # make
  84. X    # mv /vmunix /vmunix.save
  85. X    # cp vmunix /vmunix
  86. X
  87. X6.  Reboot your machine to start up the new kernel.
  88. X
  89. X7.  Now, build the two user level programs: ax25ether and ax25, and give
  90. X    it a try.
  91. X    # make
  92. X
  93. X8. Put your hostname in /etc/hosts with the correct IP address.
  94. X    44.135.145.28    ve6uug-0
  95. X
  96. X9.  Ensure that the netmask for network #44 is correct. Ussually it should
  97. X    be 0xffffff00. Put that in /etc/netmasks, like this.
  98. X    44    255.255.255.0
  99. X   (If you are running YP, you may need to rebuild the databases.
  100. X    # (cd /var/yp; make)
  101. X   )
  102. X
  103. X10. Ensure your TNC is in KISS mode, with the proper KISS timing parameters
  104. X    already set. Now we can start up the interface.
  105. X
  106. X    # ./ax25 -v ve6uug-0 ve6uug-0 /dev/ttyb
  107. X    popping module: ttcompat
  108. X    popping module: ldterm
  109. X    pushing module: ax25
  110. X    network device: ax0
  111. X    addresses: ax25 ac.8a.6c.aa.aa.8e.60 'VE6UUG-0' = ether 99:da:55:b5:d6:70
  112. X    execute: ifconfig ax0 ve6uug-0 netmask + broadcast + up
  113. X    Setting netmask of ax0 to 255.255.255.0
  114. X
  115. X    The first instance of your callsign is resolved according to /etc/hosts
  116. X    to generate an IP address. The second instance of your callsign determines
  117. X    what your AX25 hardware address is, which is what other parties use to
  118. X    actually send a packet to your hardware.
  119. X
  120. X11. Check to see if the interface has come up.
  121. X    # netstat -in
  122. X    Name  Mtu  Net/Dest      Address        Ipkts  Ierrs Opkts  Oerrs Collis Queue
  123. X    le0   1500 136.159.222.0 136.159.222.1  3871    0    1847    0    0      0
  124. X    lo0   1536 127.0.0.0     127.0.0.1      339     0    339     0    0      0
  125. X    ax0   1000 44.135.145.0  44.135.145.28  0       0    0       0    0      0
  126. X
  127. X12. Try to talk to a few other hosts, ie. telnet, finger, etc.
  128. X
  129. XBUGS:
  130. XGenerally, etherfind seems to work, but only on the second and successive
  131. Xattempts. The first attempt fails with an NIOCBIND error. No idea why.
  132. X
  133. XPackets with digipeater addresses in their header are dropped on the floor
  134. Ximmediately. Proper digipeater support cannot be easily added. (My opinion:
  135. Xdigipeating is a dumb idea).
  136. X
  137. XDTR behaviour: M_HANGUP and M_UNHANGUP streams messages are not handled
  138. Xcorrectly. Currently, it's best to <snip> your TNC's DTR line.
  139. X
  140. XOTHER NOTES:
  141. XThe kernel ARP routines can only deal with 6 byte ethernet addresses. A
  142. Xbizzare encoding scheme is used to encode AX25 7-byte addresses into these
  143. X6-byte addresses. When AX25 addresses are converted, the resulting ethernet
  144. Xaddresses always have their upper byte set to 0x99. The program ax25ether
  145. Xwill convert between AX25 addresses and ethernet addresses as shown using
  146. Xthe arp command.
  147. END_OF_FILE
  148. if test 3792 -ne `wc -c <'README'`; then
  149.     echo shar: \"'README'\" unpacked with wrong size!
  150. fi
  151. # end of 'README'
  152. fi
  153. if test -f 'ax25.8' -a "${1}" != "-c" ; then 
  154.   echo shar: Will not clobber existing file \"'ax25.8'\"
  155. else
  156. echo shar: Extracting \"'ax25.8'\" \(3814 characters\)
  157. sed "s/^X//" >'ax25.8' <<'END_OF_FILE'
  158. X.\" manual page v0.1 for ax25 pl-0
  159. X.\" SH section heading
  160. X.\" SS subsection heading
  161. X.\" LP paragraph
  162. X.\" IP indented paragraph
  163. X.\" TP hanging label
  164. X.TH AX25 8
  165. X.SH NAME
  166. Xax25 \- AX25/IP ifconfig Utility
  167. X.SH SYNOPSIS
  168. X.B ax25
  169. X[
  170. X.I \-v
  171. X]
  172. X.I <network address>
  173. X.I <ham call sign>
  174. X.I <tty_name>
  175. X.SH DESCRIPTION
  176. X.LP
  177. XAmateur packet radio enthusiasts nowadays send IP packets over radio
  178. Xlinks.  Hanging off a serial port on their computer, TNC modems are
  179. Xused to provide CSMA-like behaviour so that the single radio channel
  180. Xcan be shared between multiple stations (somewhat like how ethernet
  181. Xworks).  Packet radio is a broadcast medium, hence the TNC is
  182. Xresponsible for sharing the bandwidth with other TNC's.  The computer
  183. Xtalking to the TNC must use a protocol called KISS (a simple
  184. Xderivative of SLIP encoding) to send/receive packets to/from the TNC.
  185. X.LP
  186. XAX25 packets vary in length.  The packet header at the start of the
  187. Xpacket has four parts:
  188. X.TP
  189. X1.
  190. XA (guaranteed to be) unique source address.
  191. X.TP
  192. X2.
  193. XA destination addresses.
  194. X.TP
  195. X3.
  196. XAn AX25 packet type field.  In our case it is always set to
  197. XUI, to indicate that this is an AX25 datagram.
  198. X.TP
  199. X4.
  200. XA small number, choosing between various higher level
  201. Xprotocols, called the protocol ID.
  202. X.LP
  203. XThe addresses found in the header are a simple 7-byte encoding of the
  204. XHAM radio call sign and substation ID.  These addresses are used just
  205. Xlike ethernet hardware addresses are, to provide a unique name for
  206. Xeach station.  The protocol ID can choose between many protocols but
  207. Xusers of IP-over-AX25 under Unix are really only concerned with two
  208. XAX25 sub-protocols: ARP and IP.
  209. X.LP
  210. XAX25 packets (received via KISS encoding from the TNC) which are found
  211. Xto contain ARP or IP datagrams are decoded and handed off to the
  212. Xkernel networking code.  Similarily, the network code gives outbound
  213. Xdatagrams to the AX25 device driver, where the reverse process occurs:
  214. Xthey are encapsulated in AX25 packets and, after KISS encoding, sent
  215. Xoff to the TNC for transmission.
  216. X.LP
  217. XBoth incoming and outgoing ARP datagrams require special handling.
  218. XThe Unix kernel's internal ARP cache contains translations between
  219. X4-byte IP addresses and 6-byte ethernet addresses.  It's convenient to
  220. Xnot rewrite the kernel's ARP implementation, so an encoding scheme was
  221. Xdeveloped which converts 7-byte AX25 addresses to/from 6-byte ethernet
  222. Xaddresses.  This is too twisted to describe here, so refer to the
  223. Xdevice driver source.
  224. X.LP
  225. X.SH OPTIONS
  226. XYou must be root to run this.  It's a good idea to start it from
  227. X/etc/rc.local in the background.
  228. X.TP
  229. X.B \-v
  230. XPrint out more information while setting up the link.
  231. X.TP
  232. X.B <network address>
  233. XThis provides the IP address for the network port.  This name gets passed
  234. Xto ifconfig(8), so it can be a name out of the hosts(5) database.
  235. X.TP
  236. X.B <ham call sign>
  237. XThis is your HAM call sign, with your substation ID.
  238. X.TP
  239. X.B <tty_name>
  240. XCommunicate over the named device at 9600 baud.
  241. X.LP
  242. X.SH EXAMPLE
  243. X.IP
  244. Xax25 44.135.145.28 ve6uug-0 /dev/ttyb
  245. X\".SH FILES
  246. X.SH SEE ALSO
  247. XMike Chepponis (K3MC), Phil Karn (KA9Q).
  248. X.I The KISS TNC: A simple Host\-to\-TNC communications protocol.
  249. X.LP
  250. XPacComm.
  251. X.I Operating Manual for PacComm Packet Controllers, pg. 31.
  252. X.TP
  253. X.B RFC1055
  254. XRomkey, J.
  255. X.I A Nonstandard for Transmission of IP Datagrams Over Serial Lines: SLIP
  256. X.LP
  257. XThe README file supplied with this AX25 package.
  258. X.LP
  259. X\".SH DIAGNOSTICS
  260. X\".SH NOTES
  261. X.SH BUGS
  262. XEtherfind doesn't work as expected the first time you run it!
  263. X.LP
  264. XTNC's that toggle DTR for each packet can cause problems because
  265. Xstreams M_HANGUP and M_UNHANGUP messages are treated incorrectly. If
  266. Xyou see console messages about M_HANGUP and M_UNHANGUP, cutting the
  267. XDTR line will solve the problem.
  268. X.LP
  269. X.SH AUTHORS
  270. XTheo de Raadt \<deraadt\@lego.cuc.ab.ca\> [kernel hack]
  271. X.LP
  272. XWilliam Graham (VE6UUG) \<uug\@indigo.cuc.ab.ca\> [HAM]
  273. X.LP
  274. END_OF_FILE
  275. if test 3814 -ne `wc -c <'ax25.8'`; then
  276.     echo shar: \"'ax25.8'\" unpacked with wrong size!
  277. fi
  278. # end of 'ax25.8'
  279. fi
  280. if test -f 'ax25.c' -a "${1}" != "-c" ; then 
  281.   echo shar: Will not clobber existing file \"'ax25.c'\"
  282. else
  283. echo shar: Extracting \"'ax25.c'\" \(3577 characters\)
  284. sed "s/^X//" >'ax25.c' <<'END_OF_FILE'
  285. X#include <sys/types.h>
  286. X#include <sys/param.h>
  287. X#include <sys/socket.h>
  288. X#include <sys/stropts.h>
  289. X#include <sys/termios.h>
  290. X#include <sys/ttold.h>
  291. X#include <sys/sockio.h>
  292. X#include <sys/file.h>
  293. X#include <sys/if_ax.h>
  294. X#include <netinet/in.h>
  295. X#include <net/if.h>
  296. X#include <netinet/if_ether.h>
  297. X#include <stdio.h>
  298. X
  299. Xu_char ax25broadcastaddr[7] = {
  300. X    'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
  301. X};
  302. Xstatic struct ether_addr etherbroadcastaddr = {
  303. X    0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  304. X};
  305. X
  306. Xint
  307. Xmain(argc, argv)
  308. Xchar **argv;
  309. X{
  310. X    struct termios tios;
  311. X    u_char ax25[7];
  312. X    struct ether_addr eth;
  313. X    char cmd[128], name[64];
  314. X    u_char *cp, c;
  315. X    int verbose = 0;
  316. X    int unit = 777;
  317. X    int fd, i;
  318. X
  319. X    if(argc<4) {
  320. X        printf("usage: %s [-v] inet-addr ham-call-sign tty\n", *argv);
  321. X        exit(0);
  322. X    }
  323. X
  324. X    if( !strcmp(argv[1], "-v") ) {
  325. X        verbose = 1;
  326. X        argv++;
  327. X    }
  328. X
  329. X    fd = open(argv[3], O_RDWR);
  330. X    if(fd == -1) {
  331. X        perror("open");
  332. X        exit(1);
  333. X    }
  334. X
  335. X    while(1) {
  336. X        if(verbose)
  337. X            if(ioctl(fd, I_LOOK, name) != -1)
  338. X                printf("popping module: %s\n", name);
  339. X        if(ioctl(fd, I_POP, 0) == -1)
  340. X            break;
  341. X    }
  342. X
  343. X    if( ioctl(fd, TCGETS, &tios) <0) {
  344. X        perror("ioctl TCGETS");
  345. X        exit(1);
  346. X    }
  347. X
  348. X    tios.c_cflag  = CRTSCTS | B9600;
  349. X    tios.c_cflag |= CS8|CREAD|HUPCL;
  350. X    tios.c_iflag = IGNBRK;
  351. X    if( ioctl(fd, TCSETS, &tios) <0) {
  352. X        perror("ioctl TCSETS");
  353. X        exit(1);
  354. X    }
  355. X
  356. X    if(verbose)
  357. X        printf("pushing module: ax25\n");
  358. X    if( ioctl(fd, I_PUSH, "ax25") == -1) {
  359. X        perror("ioctl I_PUSH");
  360. X        exit(1);
  361. X    }
  362. X
  363. X    if( ioctl(fd, AXIOGUNIT, &unit) != -1) {
  364. X        if(verbose)
  365. X            printf("network device: ax%d\n", unit);
  366. X    } else {
  367. X        perror("ioctl AXIOGUNIT");
  368. X        exit(1);
  369. X    }
  370. X
  371. X    /*
  372. X     * convert the HAM call sign to an ax25_addr
  373. X     */
  374. X    i = 0;
  375. X    bzero((caddr_t)ax25, sizeof(ax25));
  376. X    for(cp=(u_char *)argv[2]; *cp && (i<6); cp++) {
  377. X        if(*cp=='-') {
  378. X            cp++;
  379. X            break;
  380. X        }
  381. X        c = islower(*cp) ? toupper(*cp) : *cp;
  382. X        ax25[i++] = (u_char)(c << 1);
  383. X    }
  384. X    while(i<6)
  385. X        ax25[i++] = (u_char)(' ' << 1);
  386. X    while(*cp=='-')
  387. X        cp++;
  388. X    if(*cp)
  389. X        ax25[6] = (u_char)(*cp << 1);
  390. X
  391. X    ax_ax2ether(ax25, ð);
  392. X    if( ioctl(fd, AXIOSHADDR, ð) == -1) {
  393. X        perror("ioctl AXIOSHADDR");
  394. X        exit(1);
  395. X    }
  396. X
  397. X    sprintf(cmd, "ifconfig ax%d %s netmask + broadcast + up",
  398. X        unit, argv[1]);
  399. X    if(verbose)
  400. X        printf("execute: %s\n", cmd);
  401. X    system(cmd);
  402. X
  403. X    while(sigpause(0)!=-1)
  404. X        ;
  405. X    return 0;
  406. X}
  407. X
  408. X
  409. X/*
  410. X * convert an ax25 address to an ether_addr
  411. X */
  412. Xax_ax2ether(axhp, ethp)
  413. Xu_char *axhp;
  414. Xstruct ether_addr *ethp;
  415. X{
  416. X    u_char c;
  417. X    int i;
  418. X
  419. X    printf("addresses: ax25 ");
  420. X    for(i=0; i<6; i++)
  421. X        printf("%02x.", axhp[i]);
  422. X    printf("%02x '", axhp[6]);
  423. X
  424. X    for(i=0; i<(7-1); i++)
  425. X        printf("%c", axhp[i]>>1);
  426. X    printf("-%c' = ether ", axhp[6]>>1);
  427. X
  428. X    if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
  429. X        sizeof(ax25broadcastaddr)) ) {
  430. X        bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
  431. X            sizeof(struct ether_addr));
  432. X        goto done;
  433. X    }
  434. X
  435. X    ethp->ether_addr_octet[0] = 0x99;
  436. X    c =  ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
  437. X    c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
  438. X    ethp->ether_addr_octet[1] = c;
  439. X    c =  ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
  440. X    c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
  441. X    ethp->ether_addr_octet[2] = c;
  442. X    c =  ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
  443. X    c |= ((((axhp[3]>>1) - ' ')     ) & 0x3f);
  444. X    ethp->ether_addr_octet[3] = c;
  445. X    c =  ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
  446. X    c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
  447. X    ethp->ether_addr_octet[4] = c;
  448. X    c =  ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
  449. X    c |= ((((axhp[6]>>1) - '0')     ) & 0x0f);
  450. X    ethp->ether_addr_octet[5] = c;
  451. X
  452. Xdone:
  453. X    for(i=0; i<sizeof(struct ether_addr)-1; i++)
  454. X        printf("%02x:", ethp->ether_addr_octet[i]);
  455. X    printf("%02x\n", ethp->ether_addr_octet[5]);
  456. X    return 0;
  457. X}
  458. X
  459. END_OF_FILE
  460. if test 3577 -ne `wc -c <'ax25.c'`; then
  461.     echo shar: \"'ax25.c'\" unpacked with wrong size!
  462. fi
  463. # end of 'ax25.c'
  464. fi
  465. if test -f 'ax25ether.c' -a "${1}" != "-c" ; then 
  466.   echo shar: Will not clobber existing file \"'ax25ether.c'\"
  467. else
  468. echo shar: Extracting \"'ax25ether.c'\" \(4192 characters\)
  469. sed "s/^X//" >'ax25ether.c' <<'END_OF_FILE'
  470. X#include <stdio.h>
  471. X#include <sys/types.h>
  472. X#include <sys/socket.h>
  473. X#include <netinet/in.h>
  474. X#include <net/if.h>
  475. X#include <netinet/if_ether.h>
  476. X#include <sys/if_ax.h>
  477. X
  478. Xu_char ax25broadcastaddr[7] = {
  479. X    'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
  480. X};
  481. Xstatic struct ether_addr etherbroadcastaddr = {
  482. X    0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  483. X};
  484. Xstatic struct ether_addr ethernulladdr;
  485. X
  486. X/*
  487. X * convert an ax25 address to an ether_addr
  488. X */
  489. Xax_ax2ether(axhp, ethp)
  490. Xu_char *axhp;
  491. Xstruct ether_addr *ethp;
  492. X{
  493. X    u_char c;
  494. X    int i;
  495. X
  496. X    for(i=0; i<6; i++)
  497. X        printf("%02x.", axhp[i]);
  498. X    printf("%02x '", axhp[6]);
  499. X
  500. X    for(i=0; i<(7-1); i++)
  501. X        printf("%c", axhp[i]>>1);
  502. X    printf("-%c' == ", axhp[6]>>1);
  503. X
  504. X    if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
  505. X        sizeof(ax25broadcastaddr)) ) {
  506. X        bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
  507. X            sizeof(struct ether_addr));
  508. X        goto done;
  509. X    }
  510. X
  511. X    ethp->ether_addr_octet[0] = 0x99;
  512. X    c =  ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
  513. X    c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
  514. X    ethp->ether_addr_octet[1] = c;
  515. X    c =  ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
  516. X    c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
  517. X    ethp->ether_addr_octet[2] = c;
  518. X    c =  ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
  519. X    c |= ((((axhp[3]>>1) - ' ')     ) & 0x3f);
  520. X    ethp->ether_addr_octet[3] = c;
  521. X    c =  ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
  522. X    c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
  523. X    ethp->ether_addr_octet[4] = c;
  524. X    c =  ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
  525. X    c |= ((((axhp[6]>>1) - '0')     ) & 0x0f);
  526. X    ethp->ether_addr_octet[5] = c;
  527. X
  528. Xdone:
  529. X    for(i=0; i<sizeof(struct ether_addr)-1; i++)
  530. X        printf("%02x:", ethp->ether_addr_octet[i]);
  531. X    printf("%02x\n", ethp->ether_addr_octet[5]);
  532. X    return 0;
  533. X}
  534. X
  535. X/*
  536. X * convert an ether_addr to an ax25 address
  537. X */
  538. Xax_ether2ax(ethp, axhp)
  539. Xstruct ether_addr *ethp;
  540. Xu_char *axhp;
  541. X{
  542. X    u_char c;
  543. X    int i;
  544. X
  545. X    for(i=0; i<sizeof(struct ether_addr)-1; i++)
  546. X        printf("%02x:", ethp->ether_addr_octet[i]);
  547. X    printf("%02x == ", ethp->ether_addr_octet[5]);
  548. X
  549. X    if( !bcmp((caddr_t)ethp, (caddr_t)ðernulladdr,
  550. X        sizeof(struct ether_addr))) {
  551. X        printf("nothing\n");
  552. X        return;
  553. X    }
  554. X    if( !bcmp((caddr_t)ethp, (caddr_t)ðerbroadcastaddr,
  555. X        sizeof(struct ether_addr))) {
  556. X        axhp[0] = 'Q' << 1;
  557. X        axhp[1] = 'S' << 1;
  558. X        axhp[2] = 'T' << 1;
  559. X        axhp[3] = ' ' << 1;
  560. X        axhp[4] = ' ' << 1;
  561. X        axhp[5] = ' ' << 1;
  562. X        axhp[6] = '0' << 1;
  563. X        goto done;
  564. X    }
  565. X
  566. X    c = ethp->ether_addr_octet[0];
  567. X    if(c != 0x99) {
  568. X        printf("[NO MAPPING]\n");
  569. X        for(i=0; i<7; i++)
  570. X            axhp[i] = (i+1) << 1;
  571. X        return;
  572. X    }
  573. X    c =  (ethp->ether_addr_octet[1] >> 2) & 0x3f;
  574. X    axhp[0] = (u_char)((c + ' ') << 1);
  575. X    c =  (ethp->ether_addr_octet[1] << 4) & 0x30;
  576. X    c |= (ethp->ether_addr_octet[2] >> 4) & 0x0f;
  577. X    axhp[1] = (u_char)((c + ' ') << 1);
  578. X    c =  (ethp->ether_addr_octet[2] << 2) & 0x3c;
  579. X    c |= (ethp->ether_addr_octet[3] >> 6) & 0x03;
  580. X    axhp[2] = (u_char)((c + ' ') << 1);
  581. X    c =  (ethp->ether_addr_octet[3]     ) & 0x3f;
  582. X    axhp[3] = (u_char)((c + ' ') << 1);
  583. X    c =  (ethp->ether_addr_octet[4] >> 2) & 0x3f;
  584. X    axhp[4] = (u_char)((c + ' ') << 1);
  585. X    c =  (ethp->ether_addr_octet[4] << 4) & 0x30;
  586. X    c |= (ethp->ether_addr_octet[5] >> 4) & 0x0f;
  587. X    axhp[5] = (u_char)((c + ' ') << 1);
  588. X    c =  (ethp->ether_addr_octet[5]     ) & 0x0f;
  589. X    axhp[6] = (u_char)((c + '0') << 1);
  590. X
  591. Xdone:
  592. X    for(i=0; i<6; i++)
  593. X        printf("%02x.", axhp[i]);
  594. X    printf("%02x '", axhp[6]);
  595. X
  596. X    for(i=0; i<6; i++)
  597. X        printf("%c", (axhp[i]>>1) & 0x7f );
  598. X    printf("-%c'\n", (axhp[6]>>1) & 0x7f );
  599. X}
  600. X
  601. Xmain(argc, argv)
  602. Xchar **argv;
  603. X{
  604. X    u_char ax25[7];
  605. X    struct ether_addr eth;
  606. X    u_char *cp, c;
  607. X    int i;
  608. X
  609. X    if(argc<3) {
  610. X        fprintf(stderr, "usage: %s af addr\n", argv[0]);
  611. X        fprintf(stderr, "\taf=ax25, ether\n");
  612. X        exit(0);
  613. X    }
  614. X
  615. X    if( !strcmp(argv[1], "ax25")) {
  616. X        i = 0;
  617. X        bzero((caddr_t)ax25, sizeof(ax25));
  618. X        for(cp=(u_char *)argv[2]; *cp && (i<6); cp++) {
  619. X            if(*cp=='-') {
  620. X                cp++;
  621. X                break;
  622. X            }
  623. X            c = islower(*cp) ? toupper(*cp) : *cp;
  624. X            ax25[i++] = (u_char)(c << 1);
  625. X        }
  626. X        while(i<6)
  627. X            ax25[i++] = (u_char)(' ' << 1);
  628. X        while(*cp=='-')
  629. X            cp++;
  630. X        if(*cp)
  631. X            ax25[6] = (u_char)(*cp << 1);
  632. X        ax_ax2ether(ax25, ð);
  633. X
  634. X    } else if( !strcmp(argv[1], "ether")) {
  635. X        bcopy((caddr_t)ether_aton(argv[2]), (caddr_t)ð,
  636. X            sizeof(struct ether_addr));
  637. X        ax_ether2ax(ð, ax25);
  638. X    } else
  639. X        printf("what?\n");
  640. X    return 0;
  641. X}
  642. END_OF_FILE
  643. if test 4192 -ne `wc -c <'ax25ether.c'`; then
  644.     echo shar: \"'ax25ether.c'\" unpacked with wrong size!
  645. fi
  646. # end of 'ax25ether.c'
  647. fi
  648. if test -f 'if_ax.h' -a "${1}" != "-c" ; then 
  649.   echo shar: Will not clobber existing file \"'if_ax.h'\"
  650. else
  651. echo shar: Extracting \"'if_ax.h'\" \(1890 characters\)
  652. sed "s/^X//" >'if_ax.h' <<'END_OF_FILE'
  653. X#ifndef _if_ax_h_
  654. X#define _if_ax_h_
  655. X
  656. X#define AXIOGUNIT    _IOR(x, 111, int)        /* get unit number */
  657. X#define AXIOSHADDR    _IOW(x, 112, struct ether_addr)    /* set ether_addr */
  658. X
  659. X#define AXSTREAMNAME    "ax25"            /* streams module name */
  660. X#define AXIFNAME    "ax"            /* interface name */
  661. X#define    AX25MTU        1000            /* max ax25 packet size */
  662. X
  663. X/* An ax25 address is encoded as a struct ether_addr so that it can fit
  664. X * in the arp tables.
  665. X *
  666. X *    encoding format in struct ether_addr
  667. X *     ________ ______ ______ ______ ______ ______ ______ _____
  668. X *    |   8    |  6   |  6   |  6   |  6   |  6   |  6   |  4  |
  669. X *    |________|______|______|______|______|______|______|_____|
  670. X *    
  671. X * The upper byte of ether_addr is set to 0x99.
  672. X *
  673. X * The next 6 6-bit fields are each filled with an ax25_addr.aa_c[] entry,
  674. X * shifted back to normal ASCII, and then offset from ASCII space
  675. X * (ie. aa_c[0] - ' ').
  676. X *
  677. X * The sid has values ASCII '0' -> ASCII '0'+15. ASCII '0' is subtraced and
  678. X * the low 4 bits of the ether_addr are set from that.
  679. X */
  680. X
  681. X/* screw digipeaters */
  682. Xstruct ax25_hdr {
  683. X    u_char        ah_dst[7], ah_src[7];
  684. X    u_char        ah_cmd;
  685. X    u_char        ah_pid;
  686. X};
  687. X
  688. X/*
  689. X * AX25 commands. All others are tossed.
  690. X */
  691. X#define    AX25CMD_UI        0x03        /* AX25 datagram */
  692. X
  693. X/*
  694. X * AX25 Protocol IDs. All others are tossed.
  695. X */
  696. X#define    AX25PID_IP        0xcc        /* ARPA IP */
  697. X#define    AX25PID_ARP        0xcd        /* ARPA ARP */
  698. X
  699. X/*
  700. X * AX25 ARP address types.
  701. X */
  702. X#define    AX25_HARDTYPE        0x0003
  703. X#define    AX25_IPTYPE        ((short)AX25PID_IP)
  704. X
  705. X/*
  706. X * KISS framing. This is SLIP.
  707. X */
  708. X#define    KISS_END        0xc0
  709. X#define KISS_ESC        0xdb
  710. X#define KISS_TEND        0xdc
  711. X#define KISS_TESC        0xdd
  712. X
  713. X/*
  714. X * KISS commands - first data byte inside the KISS packet.
  715. X */
  716. X#define    KISS_DATA        0x00
  717. X#define    KISS_TXDELAY        0x01
  718. X#define    KISS_PERSISTANCE    0x02
  719. X#define    KISS_SLOTTIME        0x03
  720. X#define    KISS_TXTAIL        0x04
  721. X#define    KISS_FULLDUPLEX        0x05
  722. X#define    KISS_HARDWARE        0x06
  723. X#define    KISS_QUIT        0xff
  724. X
  725. X#endif /* _if_ax_h_ */
  726. END_OF_FILE
  727. if test 1890 -ne `wc -c <'if_ax.h'`; then
  728.     echo shar: \"'if_ax.h'\" unpacked with wrong size!
  729. fi
  730. # end of 'if_ax.h'
  731. fi
  732. if test -f 'tty_ax.c' -a "${1}" != "-c" ; then 
  733.   echo shar: Will not clobber existing file \"'tty_ax.c'\"
  734. else
  735. echo shar: Extracting \"'tty_ax.c'\" \(23598 characters\)
  736. sed "s/^X//" >'tty_ax.c' <<'END_OF_FILE'
  737. X/*
  738. X * KISS+AX25 IP streams module for sunos 4.x
  739. X *
  740. X * Copyright 1991, 1992 by Theo de Raadt
  741. X *
  742. X * Theo de Raadt <deraadt@lego.cuc.ab.ca>
  743. X * Thanks to William Graham <uug@indigo.cuc.ab.ca> for AX25 specs.
  744. X *
  745. X * Streams ideas ripped off from PPP and SLIP implimentations for
  746. X * Sunos by Brad Clements and Rayan Zachariassen respectively.
  747. X */
  748. X#undef    DEBUG
  749. X#undef    DEBUG2
  750. X#define    AX_NIT
  751. X
  752. X#include "ax.h"
  753. X#if NAX > 0
  754. X
  755. X#include <sys/types.h>
  756. X#include <sys/param.h>
  757. X#include <sys/stream.h>
  758. X#include <sys/stropts.h>
  759. X#include <sys/dir.h>
  760. X#include <sys/signal.h>
  761. X#include <sys/user.h>
  762. X#include <sys/mbuf.h>
  763. X#include <sys/socket.h>
  764. X#include <sys/sockio.h>
  765. X#include <sys/syslog.h>
  766. X
  767. X#include <netinet/in.h>
  768. X
  769. X#include <net/if.h>
  770. X#include <net/nit_if.h>
  771. X#include <netinet/if_ether.h>
  772. X#include <sys/if_ax.h>
  773. X
  774. X#include <net/netisr.h>
  775. X
  776. X#include <netinet/in_systm.h>
  777. X#include <netinet/in_var.h>
  778. X#include <netinet/ip.h>
  779. X
  780. X#ifdef AX_NIT
  781. Xstatic struct ether_header nitheader = { {{1}}, {{2}}, ETHERTYPE_IP };
  782. Xstatic struct nit_if nif = {(caddr_t)&nitheader, sizeof(nitheader), 0, 0};
  783. X
  784. Xstatic struct ether_header nitheader_arp = { {{1}}, {{2}}, ETHERTYPE_ARP };
  785. Xstatic struct nit_if nif_arp = {(caddr_t)&nitheader_arp, sizeof(nitheader_arp), 0, 0};
  786. X#endif
  787. X
  788. Xint ax_attach();
  789. Xstatic int ax_open(), ax_close(), ax_rput(), ax_wput(), ax_wsrv();
  790. Xstatic int ax_ioctl(), ax_output();
  791. Xstatic struct mbuf *ax_btom();
  792. X
  793. Xstatic struct module_info minfo = {
  794. X    0xabce, AXSTREAMNAME, 0, INFPSZ, 16384, 4096
  795. X};
  796. X
  797. Xstatic struct qinit r_init = {
  798. X    ax_rput, NULL, ax_open, ax_close, NULL, &minfo, NULL
  799. X};
  800. X
  801. Xstatic struct qinit w_init = {
  802. X    ax_wput, ax_wsrv, ax_open, ax_close, NULL, &minfo, NULL
  803. X};
  804. X
  805. Xstruct streamtab axinfo = {
  806. X    &r_init, &w_init, NULL, NULL, NULL
  807. X};
  808. X
  809. Xstatic struct axpriv {
  810. X    struct arpcom    arpcom;
  811. X    queue_t        *q;
  812. X    u_char        *buf;
  813. X    u_char        *dp;
  814. X    u_int        inlen;
  815. X    u_char        gotesc, toobig;
  816. X} axpriv[NAX];
  817. X
  818. Xstatic u_char ax25broadcastaddr[7] = {
  819. X    'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
  820. X};
  821. Xstatic struct ether_addr ethernulladdr;
  822. X
  823. Xint
  824. Xax_attach(unit)
  825. Xint unit;
  826. X{
  827. X    register struct ifnet *ifp = &axpriv[unit].arpcom.ac_if;
  828. X
  829. X    ifp->if_name = AXIFNAME;
  830. X    ifp->if_mtu = AX25MTU;
  831. X    ifp->if_flags = IFF_BROADCAST;
  832. X    ifp->if_unit = unit;
  833. X    ifp->if_ioctl = ax_ioctl;
  834. X    ifp->if_output = ax_output;
  835. X    ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  836. X    if_attach(ifp);
  837. X    return 0;
  838. X}
  839. X
  840. Xstatic int
  841. Xax_open(q, dev, flag, sflag)
  842. Xqueue_t *q;
  843. Xdev_t dev;
  844. Xint flag, sflag;
  845. X{
  846. X    struct axpriv *axp;
  847. X    int unit, s;
  848. X
  849. X    if( !suser()) {
  850. X        u.u_error = EPERM;
  851. X        return OPENFAIL;
  852. X    }
  853. X
  854. X    s = splstr();
  855. X    for( unit=0; unit<NAX; ++unit) {
  856. X        axp = &axpriv[unit];
  857. X
  858. X        if(axp->buf)
  859. X            continue;
  860. X        if(axp->arpcom.ac_if.if_mtu == 0)
  861. X            ax_attach(unit);
  862. X        axp->arpcom.ac_if.if_flags |= IFF_RUNNING;
  863. X        axp->buf = (u_char *)kmem_alloc(AX25MTU);
  864. X        axp->dp = axp->buf + sizeof(struct ifnet *);
  865. X        axp->inlen = 0;
  866. X        axp->q = WR(q);
  867. X        WR(q)->q_ptr = q->q_ptr = (caddr_t)axp;
  868. X        (void) splx(s);
  869. X        log(LOG_INFO, "ax%d: coming up\n", unit);
  870. X        return unit;
  871. X    }
  872. X    splx(s);
  873. X    log(LOG_INFO, "ax%d: no more devices available\n", NAX);
  874. X    return OPENFAIL;
  875. X}
  876. X
  877. Xstatic int
  878. Xax_close(q, flag)
  879. Xqueue_t *q;
  880. Xint flag;
  881. X{
  882. X    struct axpriv *axp;
  883. X    int s;
  884. X
  885. X    s = splimp();
  886. X    axp = (struct axpriv *)q->q_ptr;
  887. X    if(axp) {
  888. X        log(LOG_INFO, "ax%d: going down\n", axp->arpcom.ac_if.if_unit);
  889. X        if_down(&axp->arpcom.ac_if);
  890. X        axp->arpcom.ac_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
  891. X        if(axp->buf)
  892. X            kmem_free(axp->buf, AX25MTU);
  893. X        axp->buf = NULL;
  894. X        axp->q = NULL;
  895. X    }
  896. X    (void) splx(s);
  897. X}
  898. X
  899. Xstatic int
  900. Xax_wput(q, mp)
  901. Xqueue_t *q;
  902. Xmblk_t *mp;
  903. X{
  904. X    struct axpriv *axp;
  905. X    char ax25[7];
  906. X    struct iocblk *iocp;
  907. X
  908. X    switch(mp->b_datap->db_type) {
  909. X    case M_FLUSH:
  910. X        if(*mp->b_rptr & FLUSHW)
  911. X            flushq(q, FLUSHDATA);
  912. X        putnext(q, mp);
  913. X        break;
  914. X    case M_DATA:
  915. X        putq(q, mp);
  916. X        break;
  917. X    case M_IOCTL:
  918. X        iocp = (struct iocblk *)mp->b_rptr;
  919. X        axp = (struct axpriv *)q->q_ptr;
  920. X        switch(iocp->ioc_cmd) {
  921. X        case AXIOSHADDR:
  922. X            bcopy((caddr_t)mp->b_cont->b_rptr,
  923. X                (caddr_t)&axp->arpcom.ac_enaddr,
  924. X                sizeof(struct ether_addr));
  925. X            mp->b_datap->db_type = M_IOCACK;
  926. X            iocp->ioc_rval = iocp->ioc_count = iocp->ioc_error = 0;
  927. X            qreply(q, mp);
  928. X            log(LOG_INFO, "ax%d: ether %2x:%2x:%2x:%2x:%2x:%2x ax25 ",
  929. X                axp->arpcom.ac_if.if_unit,
  930. X                axp->arpcom.ac_enaddr.ether_addr_octet[0],
  931. X                axp->arpcom.ac_enaddr.ether_addr_octet[1],
  932. X                axp->arpcom.ac_enaddr.ether_addr_octet[2],
  933. X                axp->arpcom.ac_enaddr.ether_addr_octet[3],
  934. X                axp->arpcom.ac_enaddr.ether_addr_octet[4],
  935. X                axp->arpcom.ac_enaddr.ether_addr_octet[5]);
  936. X            ax_ether2ax(&axp->arpcom.ac_enaddr, ax25);
  937. X            print_ax25addr(ax25);
  938. X            printf("\n");
  939. X            return;
  940. X        case AXIOGUNIT:
  941. X            iocp->ioc_rval = 0;
  942. X            if( mp->b_cont = allocb(sizeof(int), BPRI_MED) ) {
  943. X                u_char *cp = mp->b_cont->b_wptr;
  944. X
  945. X                mp->b_datap->db_type = M_IOCACK;
  946. X                *((int *)cp) = axp->arpcom.ac_if.if_unit;
  947. X                mp->b_cont->b_wptr += sizeof(int);
  948. X                iocp->ioc_count = sizeof(int);
  949. X                iocp->ioc_error = 0;
  950. X                qreply(q, mp);
  951. X                break;
  952. X            }
  953. X            iocp->ioc_error = ENOSR;
  954. X            mp->b_datap->db_type = M_IOCNAK;
  955. X            qreply(q, mp);
  956. X            return;
  957. X        default:
  958. X            log(LOG_INFO, "ax%d: unknown ioc %8x\n",
  959. X                axp->arpcom.ac_if.if_unit, iocp->ioc_cmd);
  960. X            putnext(q, mp);
  961. X            return;
  962. X        }
  963. X        break;
  964. X    default:
  965. X        putnext(q, mp);
  966. X    }
  967. X}
  968. X
  969. Xstatic int
  970. Xax_rput(q, mp)
  971. Xqueue_t *q;
  972. Xmblk_t *mp;
  973. X{
  974. X    struct axpriv *axp = (struct axpriv *)q->q_ptr;
  975. X    struct ifnet *ifp;
  976. X    register u_char c, *rp;
  977. X    register mblk_t *bp;
  978. X    struct mbuf *m;
  979. X    int proto, forus, s;
  980. X
  981. X    if( axp==NULL ) {
  982. X        log(LOG_INFO, "ax_rput: axp is NULL\n");
  983. X        freemsg(mp);
  984. X        return;
  985. X    }
  986. X    if( axp->buf==NULL ) {
  987. X        log(LOG_INFO, "ax_rput: axp->buf is NULL\n");
  988. X        freemsg(mp);
  989. X        return;
  990. X    }
  991. X
  992. X    ifp = &axp->arpcom.ac_if;
  993. X    switch(mp->b_datap->db_type) {
  994. X    case M_DATA:
  995. X        break;
  996. X    case M_FLUSH:
  997. X        if(*mp->b_rptr & FLUSHR)
  998. X            flushq(q, FLUSHDATA);
  999. X        putnext(q, mp);
  1000. X        return;
  1001. X    case M_UNHANGUP:
  1002. X        log(LOG_INFO, "ax%d: M_UNHANGUP\n", ifp->if_unit);
  1003. X        axp->q = WR(q);        /* hook us up again */
  1004. X        putnext(q, mp);
  1005. X        putctl1(q->q_next, M_PCSIG, SIGURG);
  1006. X        return;
  1007. X    case M_HANGUP:
  1008. X        log(LOG_INFO, "ax%d: M_HANGUP\n", ifp->if_unit);
  1009. X        s = splstr();
  1010. X        axp->q = NULL;        /* cause ax_output to return ENETDOWN */
  1011. X        (void) splx(s);
  1012. X        putnext(q, mp);
  1013. X        return;
  1014. X    case M_BREAK:
  1015. X    case M_IOCACK:
  1016. X        putnext(q, mp);
  1017. X        return;
  1018. X    default:
  1019. X        log(LOG_INFO, "ax%d: rput streams message type %d discarded\n",
  1020. X            ifp->if_unit, mp->b_datap->db_type);
  1021. X        putnext(q, mp);
  1022. X        return;
  1023. X    }
  1024. X
  1025. X    /*
  1026. X     * Perform the KISS protocol on the streams message, and add the bytes
  1027. X     * to a packet reconstruction buffer. When a complete AX25 packet has
  1028. X     * been collected, strip the AX25 layer and provide the IP (or ARP) packet
  1029. X     * inside to the networking code.
  1030. X     */
  1031. X    for( bp=mp; bp; bp=bp->b_cont) {
  1032. X        rp = bp->b_rptr;
  1033. X        while( rp < bp->b_wptr) {
  1034. X            c = *rp++;
  1035. X            /*printf("K %2x\n", c);*/
  1036. X            if(axp->gotesc) {
  1037. X                axp->gotesc = 0;
  1038. X                if(c==KISS_TEND)
  1039. X                    c = KISS_END;
  1040. X                else if(c==KISS_TESC)
  1041. X                    c = KISS_ESC;
  1042. X#ifdef DEBUG
  1043. X                else
  1044. X                    log(LOG_INFO, "ax%d: kiss ESC error (c=%d)\n",
  1045. X                        ifp->if_unit, c);
  1046. X#endif
  1047. X            } else if(c==KISS_END) {
  1048. X                if(axp->toobig) {
  1049. X                    axp->toobig = 0;
  1050. X                    /*printf("ax%d: packet toobig\n",
  1051. X                        ifp->if_unit);*/
  1052. X                    axp->inlen = 0;
  1053. X                    continue;
  1054. X                }
  1055. X                if(axp->inlen==0)
  1056. X                    continue;
  1057. X            
  1058. X                /*
  1059. X                 * buf contains KISS_DATA followed by an AX25
  1060. X                 * packet. Extract the IP packet lurking inside
  1061. X                 * AX25 packet..
  1062. X                 */
  1063. X                m = ax_btom(axp, &proto, &forus);
  1064. X                axp->dp = axp->buf + sizeof(struct ifnet *);
  1065. X                ifp->if_ipackets++;
  1066. X                axp->inlen = 0;
  1067. X                if(!m) {
  1068. X                    ifp->if_ierrors++;
  1069. X                    continue;
  1070. X                }
  1071. X
  1072. X                switch(proto) {
  1073. X                case AX25PID_IP:
  1074. X#ifdef AX_NIT
  1075. X                    if(ifp->if_flags & IFF_PROMISC) {
  1076. X                        struct mbuf *nm = m;
  1077. X                        int len = 0;
  1078. X
  1079. X                        do {
  1080. X                            len += nm->m_len;
  1081. X                        } while( nm=nm->m_next );
  1082. X                        len -= sizeof(struct ifnet *);
  1083. X                        m->m_off += sizeof(struct ifnet *);
  1084. X                        nif.nif_bodylen = len;
  1085. X                        snit_intr(&axp->arpcom, m, &nif);
  1086. X                        m->m_off -= sizeof(struct ifnet *);
  1087. X                    }                    
  1088. X#endif
  1089. X                    if(!forus) {
  1090. X                        m_freem(m);
  1091. X                        break;
  1092. X                    }
  1093. X                    s = splimp();
  1094. X                    if( IF_QFULL(&ipintrq) ) {
  1095. X                        IF_DROP(&ipintrq);
  1096. X                        ifp->if_ierrors++;
  1097. X                        m_freem(m);
  1098. X                        (void) splx(s);
  1099. X                    } else {
  1100. X                        IF_ENQUEUE(&ipintrq, m);
  1101. X                        schednetisr(NETISR_IP);
  1102. X                        (void) splx(s);
  1103. X#ifdef DEBUG
  1104. X                        log(LOG_INFO, "handing off to IP\n");
  1105. X#endif
  1106. X                    }
  1107. X                    break;
  1108. X                case AX25PID_ARP:
  1109. X#ifdef AX_NIT
  1110. X                    if(ifp->if_flags & IFF_PROMISC) {
  1111. X                        struct mbuf *nm = m;
  1112. X                        int len = 0;
  1113. X
  1114. X                        do {
  1115. X                            len += nm->m_len;
  1116. X                        } while( nm=nm->m_next );
  1117. X                        len -= sizeof(struct ifnet *);
  1118. X                        m->m_off += sizeof(struct ifnet *);
  1119. X                        nif_arp.nif_bodylen = len;
  1120. X                        snit_intr(&axp->arpcom, m, &nif_arp);
  1121. X                        m->m_off -= sizeof(struct ifnet *);
  1122. X                    }                    
  1123. X#endif
  1124. X                    if(!forus) {
  1125. X                        m_freem(m);
  1126. X                        break;
  1127. X                    }
  1128. X#ifdef DEBUG
  1129. X                    printf("[INCOMING ethernet arp packet]");
  1130. X                    ax25_arpdebug(m);
  1131. X#endif
  1132. X                    arpinput(&axp->arpcom, m);
  1133. X                    break;
  1134. X                default:
  1135. X#ifdef DEBUG2
  1136. X                    printf("ax%d: unknown protocol %d\n",
  1137. X                        ifp->if_unit,
  1138. X                        proto);
  1139. X#endif
  1140. X                    m_freem(m);
  1141. X                    break;
  1142. X                }
  1143. X                continue;
  1144. X            } else if(c==KISS_ESC) {
  1145. X                axp->gotesc = 1;
  1146. X                continue;
  1147. X            }
  1148. X            if(++axp->inlen > AX25MTU) {
  1149. X                if(axp->toobig)
  1150. X                    continue;
  1151. X                axp->toobig = 1;
  1152. X                ifp->if_ierrors++;
  1153. X                axp->dp = axp->buf + sizeof(struct ifnet *);
  1154. X                continue;
  1155. X            } else
  1156. X                *axp->dp++ = c;
  1157. X        }
  1158. X        bp->b_rptr = rp;
  1159. X    }
  1160. X    freemsg(mp);
  1161. X    return;
  1162. X}
  1163. X
  1164. X
  1165. Xstatic struct mbuf *
  1166. Xax_btom(axp, protop, forusp)
  1167. Xstruct axpriv *axp;
  1168. Xint *protop, *forusp;
  1169. X{
  1170. X    struct ax25_hdr *ax;
  1171. X    struct mbuf *m, **mp, *top = NULL;
  1172. X    struct ifnet *ifp;
  1173. X    struct ether_addr oureth;
  1174. X    int len, count;
  1175. X    caddr_t cp;
  1176. X
  1177. X    ax = (struct ax25_hdr *)(axp->buf + sizeof(struct ifnet *) + 1);
  1178. X
  1179. X    /*
  1180. X     * digipeaters are not supported (they could be supported - could
  1181. X     * correct the AX25 packet's fields, KISS encode it, and send a
  1182. X     * message downstream to the TNC.)
  1183. X     * 
  1184. X     * The IP packet must come in an AX25 UI frame.
  1185. X     */
  1186. X    if(ax->ah_cmd != AX25CMD_UI) {
  1187. X#ifdef DEBUG2
  1188. X        printf("ax%d: ax25 frame not UI, cmd=%2x\n",
  1189. X            axp->arpcom.ac_if.if_unit, ax->ah_cmd);
  1190. X#endif
  1191. X        return NULL;
  1192. X    }
  1193. X
  1194. X#ifdef DEBUG2
  1195. X    printf("ax%d: ", axp->arpcom.ac_if.if_unit);
  1196. X    print_ax25addr(ax->ah_src);
  1197. X    printf("->");
  1198. X    print_ax25addr(ax->ah_dst);
  1199. X    printf(" [%d]\n", axp->inlen - sizeof(struct ax25_hdr) - 1);
  1200. X#endif
  1201. X
  1202. X    /* 
  1203. X     * is this packet to us?
  1204. X     */
  1205. X    *forusp = 1;
  1206. X    ax_ax2ether(ax->ah_dst, &oureth);
  1207. X    if( bcmp((caddr_t)&oureth, (caddr_t)&axp->arpcom.ac_enaddr,
  1208. X        sizeof oureth) &&
  1209. X        bcmp((caddr_t)ax25broadcastaddr, (caddr_t)&axp->arpcom.ac_enaddr,
  1210. X        sizeof oureth)) {
  1211. X        *forusp = 0;
  1212. X    }
  1213. X
  1214. X    /*
  1215. X     * packet not for us, and not promisc mode --> can out.
  1216. X     */
  1217. X    if( !(axp->arpcom.ac_if.if_flags & IFF_PROMISC) && *forusp==0)
  1218. X        return NULL;
  1219. X
  1220. X    /*
  1221. X     * check acceptable protocols
  1222. X     */
  1223. X    switch(ax->ah_pid) {
  1224. X    case AX25PID_IP:
  1225. X    case AX25PID_ARP:
  1226. X        break;
  1227. X    default:
  1228. X#ifdef DEBUG2
  1229. X        printf("ax%d: packet discarded - protocol %d\n",
  1230. X            axp->arpcom.ac_if.if_unit, ax->ah_pid);
  1231. X#endif
  1232. X        return NULL;
  1233. X    }
  1234. X
  1235. X    *protop = (int)(ax->ah_pid);
  1236. X    ifp = &axp->arpcom.ac_if;
  1237. X    cp = (caddr_t)(axp->buf + sizeof(struct ifnet *) + 1 + sizeof(struct ax25_hdr));
  1238. X    mp = ⊤
  1239. X    len = axp->inlen - 1 - sizeof(struct ax25_hdr);
  1240. X    while(len>0) {
  1241. X        MGET(m, M_DONTWAIT, MT_DATA);
  1242. X        if(m == NULL) {
  1243. X            if(top)
  1244. X                m_freem(top);
  1245. X            return NULL;
  1246. X        }
  1247. X        *mp = m;
  1248. X        if(ifp) {
  1249. X            m->m_off += sizeof(ifp);
  1250. X            count = MIN(len, MLEN - sizeof(ifp));
  1251. X            bcopy(cp, mtod(m, caddr_t), count);
  1252. X            m->m_len = count;
  1253. X            m->m_off -= sizeof(ifp);
  1254. X            m->m_len += sizeof(ifp);
  1255. X            *mtod(m, struct ifnet **) = ifp;
  1256. X            ifp = NULL;
  1257. X        } else {
  1258. X            count = MIN(len, MLEN);
  1259. X            bcopy(cp, mtod(m, caddr_t), count);
  1260. X            m->m_len = count;
  1261. X        }
  1262. X        cp += count;
  1263. X        len -= count;
  1264. X        mp = &m->m_next;
  1265. X    }
  1266. X    if(ax->ah_pid== AX25PID_ARP) {
  1267. X        top->m_off += sizeof(ifp);    /* XXX ax_ax2etherarp() weak */
  1268. X        ax_ax2etherarp(top);
  1269. X        top->m_off -= sizeof(ifp);
  1270. X    }
  1271. X
  1272. X    return top;
  1273. X}
  1274. X
  1275. X
  1276. Xstatic int
  1277. Xax_wsrv(q)
  1278. Xqueue_t *q;
  1279. X{
  1280. X    register mblk_t *mp;
  1281. X
  1282. X    while( mp=getq(q) ) {
  1283. X        if( !canput(q->q_next)) {
  1284. X            putbq(q, mp);
  1285. X            return;
  1286. X        }
  1287. X        putnext(q, mp);
  1288. X    }
  1289. X}
  1290. X
  1291. X/* %%% ifconfig ether #:#:#:#:#:# not working */
  1292. Xstatic int
  1293. Xax_ioctl(ifp, cmd, data)
  1294. Xstruct ifnet *ifp;
  1295. Xint cmd;
  1296. Xcaddr_t data;
  1297. X{
  1298. X    register struct ifaddr *ifa = (struct ifaddr *)data;
  1299. X    register struct ifreq *ifr = (struct ifreq *)data;
  1300. X    int error = 0, s;
  1301. X
  1302. X    if(ifa==NULL)
  1303. X        return EFAULT;
  1304. X    s = splimp();
  1305. X    switch(cmd) {
  1306. X    case SIOCSIFFLAGS:
  1307. X        if(!data)        /* IFF_PROMISC change */
  1308. X            break;
  1309. X        if(!suser()) {
  1310. X            error = EPERM;
  1311. X            break;
  1312. X        }
  1313. X        ifp->if_flags &= IFF_CANTCHANGE;
  1314. X        ifp->if_flags |= (ifr->ifr_flags & ~IFF_CANTCHANGE);
  1315. X        break;
  1316. X    case SIOCGIFFLAGS:
  1317. X        ifr->ifr_flags = ifp->if_flags;
  1318. X        break;
  1319. X    case SIOCSIFADDR:
  1320. X        switch(ifa->ifa_addr.sa_family) {
  1321. X        case AF_INET:
  1322. X            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
  1323. X            ifp->if_flags |= IFF_UP;
  1324. X            break;
  1325. X        default:
  1326. X            error = EAFNOSUPPORT;
  1327. X            break;
  1328. X        }
  1329. X        break;
  1330. X    case SIOCSIFBRDADDR:
  1331. X        if(ifa->ifa_addr.sa_family != AF_INET)
  1332. X            error = EAFNOSUPPORT;
  1333. X        break;
  1334. X    case SIOCSIFNETMASK:
  1335. X        if(ifa->ifa_addr.sa_family != AF_INET)
  1336. X            error = EAFNOSUPPORT;
  1337. X        break;
  1338. X    default:
  1339. X        error = EINVAL;
  1340. X    }
  1341. X    (void) splx(s);
  1342. X    return error;
  1343. X}
  1344. X
  1345. Xstatic int
  1346. Xax_output(ifp, m0, dst)
  1347. Xstruct ifnet *ifp;
  1348. Xstruct mbuf *m0;
  1349. Xstruct sockaddr *dst;
  1350. X{
  1351. X    struct axpriv *axp;
  1352. X    struct ax25_hdr ax25;
  1353. X    struct ether_header *eth;
  1354. X    struct mbuf *m = m0;
  1355. X    int i, len, s, n;
  1356. X    struct in_addr idst;
  1357. X    u_char *cp, *cp2;
  1358. X    mblk_t *mp;
  1359. X
  1360. X    axp = &axpriv[ifp->if_unit];
  1361. X    if(axp->q == NULL)
  1362. X        return ENETDOWN;
  1363. X
  1364. X    /* printf("ax%d: trying to send packet\n", ifp->if_unit); */
  1365. X
  1366. X    switch(dst->sa_family) {
  1367. X    case AF_INET:
  1368. X#ifdef AX_NIT
  1369. X        if(axp->arpcom.ac_if.if_flags & IFF_PROMISC) {
  1370. X            struct mbuf *nm = m0;
  1371. X            int len = 0;
  1372. X
  1373. X            do {
  1374. X                len += nm->m_len;
  1375. X            } while( nm=nm->m_next );
  1376. X            nif.nif_bodylen = len;
  1377. X            snit_intr(&axp->arpcom, m0, &nif);
  1378. X        }                    
  1379. X
  1380. X#endif
  1381. X        idst = ((struct sockaddr_in *)dst)->sin_addr;
  1382. X        ((struct arpcom *)ifp)->ac_lastip = idst;
  1383. X        m = m0;
  1384. X        if( !arpresolve((struct arpcom *)ifp, m)) {
  1385. X            return 0;
  1386. X        }
  1387. X#ifdef DEBUG2
  1388. X        len = 0;
  1389. X        for(m=m0; m; m=m->m_next) {
  1390. X            cp = mtod(m, u_char *);
  1391. X            n = m->m_len;
  1392. X            while(n-->0) {
  1393. X                if( !(len++ % 16) )
  1394. X                    printf("\n\t");
  1395. X                printf("%2x ", *cp++);
  1396. X            }
  1397. X        }
  1398. X        if( len % 16 )
  1399. X            printf("\n");
  1400. X#endif
  1401. X        ax25.ah_pid = AX25PID_IP;
  1402. X        ax_ether2ax(&((struct arpcom *)ifp)->ac_enaddr, ax25.ah_src);
  1403. X        ax_ether2ax(&((struct arpcom *)ifp)->ac_lastarp, ax25.ah_dst);
  1404. X#ifdef DEBUG2
  1405. X        printf("ax%d: sending to ", ifp->if_unit);
  1406. X        print_ax25addr(ax25.ah_dst);
  1407. X        printf("\n");
  1408. X#endif
  1409. X        break;
  1410. X    case AF_UNSPEC:
  1411. X        eth = (struct ether_header *)dst->sa_data;
  1412. X        switch(eth->ether_type) {
  1413. X        case ETHERTYPE_ARP:
  1414. X        case ETHERTYPE_REVARP:
  1415. X#ifdef AX_NIT
  1416. X        if(axp->arpcom.ac_if.if_flags & IFF_PROMISC) {
  1417. X            struct mbuf *nm = m0;
  1418. X            int len = 0;
  1419. X
  1420. X            do {
  1421. X                len += nm->m_len;
  1422. X            } while( nm=nm->m_next );
  1423. X            nif_arp.nif_bodylen = len;
  1424. X            snit_intr(&axp->arpcom, m0, &nif_arp);
  1425. X        }                    
  1426. X
  1427. X#endif
  1428. X#ifdef DEBUG2
  1429. X            printf("AF_UNSPEC: ARP\n");
  1430. X            printf("[ethernet arp packet]");
  1431. X            len = 0;
  1432. X            for(m=m0; m; m=m->m_next) {
  1433. X                cp = mtod(m, u_char *);
  1434. X                n = m->m_len;
  1435. X                while(n-->0) {
  1436. X                    if( !(len++ % 16) )
  1437. X                        printf("\n\t");
  1438. X                    printf("%2x ", *cp++);
  1439. X                }
  1440. X            }
  1441. X            if( len % 16 )
  1442. X                printf("\n");
  1443. X#endif
  1444. X
  1445. X            ax_ether2axarp(m0);
  1446. X            ax25.ah_pid = AX25PID_ARP;
  1447. X            ax_ether2ax(&((struct arpcom *)ifp)->ac_enaddr, ax25.ah_src);
  1448. X            ax_ether2ax(ð->ether_dhost, ax25.ah_dst);
  1449. X#ifdef DEBUG2
  1450. X            printf("[AX25 arp packet]");
  1451. X#endif
  1452. X            break;
  1453. X        default:
  1454. X            printf("AF_UNSPEC: unknown ether_type %4x",
  1455. X                ntohs(eth->ether_type));
  1456. X            ax25.ah_pid = AX25PID_IP;    /* wrong */
  1457. X            ax_ether2ax(ð->ether_shost, ax25.ah_src);
  1458. X            ax_ether2ax(ð->ether_dhost, ax25.ah_dst);
  1459. X            break;
  1460. X        }
  1461. X
  1462. X#ifdef DEBUG2
  1463. X        len = 0;
  1464. X        for(m=m0; m; m=m->m_next) {
  1465. X            cp = mtod(m, u_char *);
  1466. X            n = m->m_len;
  1467. X            while(n-->0) {
  1468. X                if( !(len++ % 16) )
  1469. X                    printf("\n\t");
  1470. X                printf("%2x ", *cp++);
  1471. X            }
  1472. X        }
  1473. X        if( len % 16 )
  1474. X            printf("\n");
  1475. X#endif
  1476. X
  1477. X        break;
  1478. X    default:
  1479. X        log(LOG_INFO, "ax%d: cannot handle af%d\n", ifp->if_unit,
  1480. X            dst->sa_family);
  1481. X        m_freem(m0);
  1482. X        return EAFNOSUPPORT;
  1483. X    }
  1484. X    
  1485. X    ax25.ah_cmd = AX25CMD_UI;
  1486. X    ax25.ah_src[6] |= 0x01;    /* %%% set low bit on src */
  1487. X
  1488. X    /*
  1489. X     * run through the ax25_hdr and the packet buffer counting
  1490. X     * how much space we need for KISS encoding.
  1491. X     */
  1492. X    len = 2;    /* KISS_END, KISS_DATA */
  1493. X    for(i=0, cp=(u_char *)&ax25; i< sizeof(ax25); i++, cp++) {
  1494. X        len++;
  1495. X        if(*cp==KISS_END || *cp==KISS_ESC)
  1496. X            len++;
  1497. X    }
  1498. X    for(m=m0; m; m=m->m_next) {
  1499. X        cp = mtod(m, u_char *);
  1500. X        for(i=0; i< m->m_len; i++, cp++) {
  1501. X            len++;
  1502. X            if(*cp==KISS_END || *cp==KISS_ESC)
  1503. X                len++;
  1504. X        }
  1505. X    }
  1506. X    len++;        /* KISS_END */
  1507. X
  1508. X    if( !(mp = allocb(len, BPRI_MED)) ) {
  1509. X        log(LOG_INFO, "ax%d: ax_output cannot allocb %d bytes\n",
  1510. X            ifp->if_unit, len);
  1511. X        m_freem(m0);
  1512. X        return ENOSR;
  1513. X    }
  1514. X
  1515. X#ifdef DEBUG2
  1516. X    cp2 = mp->b_wptr;
  1517. X#endif
  1518. X
  1519. X    /*
  1520. X     * KISS-format the ax25 header and data into mp.
  1521. X     */
  1522. X    *mp->b_wptr++ = KISS_END;
  1523. X    *mp->b_wptr++ = KISS_DATA;
  1524. X    for(i=0, cp=(u_char *)&ax25; i<sizeof(ax25); i++, cp++) {
  1525. X        switch(*cp) {
  1526. X        case KISS_END:
  1527. X            *mp->b_wptr++ = KISS_ESC;
  1528. X            *mp->b_wptr++ = KISS_TEND;
  1529. X            break;
  1530. X        case KISS_ESC:
  1531. X            *mp->b_wptr++ = KISS_ESC;
  1532. X            *mp->b_wptr++ = KISS_TESC;
  1533. X            break;
  1534. X        default:
  1535. X            *mp->b_wptr++ = *cp;
  1536. X            break;
  1537. X        }
  1538. X    }
  1539. X    for(m=m0; m; m=m->m_next) {
  1540. X        cp = mtod(m, u_char *);
  1541. X        for(i=0; i< m->m_len; i++, cp++) {
  1542. X            switch(*cp) {
  1543. X            case KISS_END:
  1544. X                *mp->b_wptr++ = KISS_ESC;
  1545. X                *mp->b_wptr++ = KISS_TEND;
  1546. X                break;
  1547. X            case KISS_ESC:
  1548. X                *mp->b_wptr++ = KISS_ESC;
  1549. X                *mp->b_wptr++ = KISS_TESC;
  1550. X                break;
  1551. X            default:
  1552. X                *mp->b_wptr++ = *cp;
  1553. X                break;
  1554. X            }
  1555. X        }
  1556. X    }
  1557. X    *mp->b_wptr++ = KISS_END;    /* superfluous, really */
  1558. X
  1559. X#ifdef DEBUG2
  1560. X    printf("actual serial output:\n");
  1561. X    while(cp2 < mp->b_wptr)
  1562. X        printf("%2x ", *cp2++);
  1563. X    printf("\n");
  1564. X#endif
  1565. X
  1566. X    s = splstr();
  1567. X    if(axp->q)
  1568. X        putq(axp->q, mp);
  1569. X    else
  1570. X        freemsg(mp);
  1571. X    (void) splx(s);
  1572. X    m_freem(m0);
  1573. X    return 0;
  1574. X}
  1575. X
  1576. X/*
  1577. X * convert an ethernet ARP packet to an AX25 ARP packet. The AX25 frame
  1578. X * header is not included.
  1579. X */
  1580. Xax_ether2axarp(m)
  1581. Xstruct mbuf *m;
  1582. X{
  1583. X    struct arphdr *arp = mtod(m, struct arphdr *);
  1584. X    struct ether_addr eth1, eth2;
  1585. X    struct in_addr in1, in2;
  1586. X    caddr_t cp;
  1587. X
  1588. X    arp->ar_hrd = AX25_HARDTYPE;
  1589. X    arp->ar_pro = AX25_IPTYPE;
  1590. X    arp->ar_hln = 7;
  1591. X
  1592. X    cp = ((caddr_t)arp) + sizeof(struct arphdr);
  1593. X    bcopy(cp, (caddr_t)ð1, sizeof(struct ether_addr));
  1594. X    cp += sizeof(struct ether_addr);
  1595. X    bcopy(cp, (caddr_t)&in1, sizeof(struct in_addr));
  1596. X    cp += sizeof(struct in_addr);
  1597. X    bcopy(cp, (caddr_t)ð2, sizeof(struct ether_addr));
  1598. X    cp += sizeof(struct ether_addr);
  1599. X    bcopy(cp, (caddr_t)&in2, sizeof(struct in_addr));
  1600. X
  1601. X    cp = ((caddr_t)arp) + sizeof(struct arphdr);
  1602. X    ax_ether2ax(ð1, (u_char *)cp);
  1603. X    cp += 7;
  1604. X    bcopy((caddr_t)&in1, cp, sizeof(struct in_addr));
  1605. X    cp += sizeof(struct in_addr);
  1606. X    ax_ether2ax(ð2, (u_char *)cp);
  1607. X    cp += 7;
  1608. X    bcopy((caddr_t)&in2, cp, sizeof(struct in_addr));
  1609. X
  1610. X    m->m_len += 2;
  1611. X    return 0;
  1612. X}
  1613. X
  1614. X/*
  1615. X * convert an AX25 ARP packet to an ethernet ARP packet. The AX25 frame
  1616. X * is assumed to have been already stripped off.
  1617. X */
  1618. Xax_ax2etherarp(m)
  1619. Xstruct mbuf *m;
  1620. X{
  1621. X    struct arphdr *arp = mtod(m, struct arphdr *);
  1622. X    u_char axa1[7], axa2[7];
  1623. X    struct in_addr in1, in2;
  1624. X    caddr_t cp;
  1625. X
  1626. X#ifdef DEBUG2
  1627. X    printf("[INCOMING AX25 arp packet]");
  1628. X    ax25_arpdebug(m);
  1629. X#endif
  1630. X
  1631. X    arp->ar_hrd = ARPHRD_ETHER;
  1632. X    arp->ar_pro = ETHERTYPE_IP;
  1633. X    arp->ar_hln = sizeof(struct ether_addr);
  1634. X
  1635. X    cp = ((caddr_t)arp) + sizeof(struct arphdr);
  1636. X    bcopy(cp, (caddr_t)axa1, 7);
  1637. X    cp += 7;
  1638. X    bcopy(cp, (caddr_t)&in1, sizeof(struct in_addr));
  1639. X    cp += sizeof(struct in_addr);
  1640. X    bcopy(cp, (caddr_t)axa2, 7);
  1641. X    cp += 7;
  1642. X    bcopy(cp, (caddr_t)&in2, sizeof(struct in_addr));
  1643. X
  1644. X    cp = ((caddr_t)arp) + sizeof(struct arphdr);
  1645. X    ax_ax2ether(axa1, (struct ether_addr *)cp);
  1646. X    cp += sizeof(struct ether_addr);
  1647. X    bcopy((caddr_t)&in1, cp, sizeof(struct in_addr));
  1648. X    cp += sizeof(struct in_addr);
  1649. X    ax_ax2ether(axa2, (struct ether_addr *)cp);
  1650. X    cp += sizeof(struct ether_addr);
  1651. X    bcopy((caddr_t)&in2, cp, sizeof(struct in_addr));
  1652. X
  1653. X    m->m_len -= 2;
  1654. X    return 0;
  1655. X}
  1656. X
  1657. X/*
  1658. X * convert an ax25_addr to an ether_addr
  1659. X */
  1660. Xax_ax2ether(axhp, ethp)
  1661. Xu_char *axhp;
  1662. Xstruct ether_addr *ethp;
  1663. X{
  1664. X    u_char c;
  1665. X    int i;
  1666. X
  1667. X#ifdef DEBUG2
  1668. X    for(i=0; i<6; i++)
  1669. X        printf("%2x.", axhp[i]);
  1670. X    printf("%2x '", axhp[6]);
  1671. X
  1672. X    for(i=0; i<(7-1); i++)
  1673. X        printf("%c", (axhp[i]>>1) & 0x7f );
  1674. X    printf("-%c' == ", (axhp[6]&0x7f)>>1 & 0x7f );
  1675. X#endif
  1676. X
  1677. X    if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
  1678. X        sizeof(ax25broadcastaddr)) ) {
  1679. X        bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
  1680. X            sizeof(struct ether_addr));
  1681. X        goto done;
  1682. X    }
  1683. X
  1684. X    ethp->ether_addr_octet[0] = 0x99;
  1685. X    c =  ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
  1686. X    c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
  1687. X    ethp->ether_addr_octet[1] = c;
  1688. X    c =  ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
  1689. X    c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
  1690. X    ethp->ether_addr_octet[2] = c;
  1691. X    c =  ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
  1692. X    c |= ((((axhp[3]>>1) - ' ')     ) & 0x3f);
  1693. X    ethp->ether_addr_octet[3] = c;
  1694. X    c =  ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
  1695. X    c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
  1696. X    ethp->ether_addr_octet[4] = c;
  1697. X    c =  ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
  1698. X    c |= (((((axhp[6]&0x7f)>>1) - '0')     ) & 0x0f);
  1699. X    ethp->ether_addr_octet[5] = c;
  1700. X
  1701. Xdone:
  1702. X#ifdef DEBUG2
  1703. X    for(i=0; i<sizeof(struct ether_addr)-1; i++)
  1704. X        printf("%2x:", ethp->ether_addr_octet[i]);
  1705. X    printf("%2x\n", ethp->ether_addr_octet[5]);
  1706. X#endif
  1707. X    return 0;
  1708. X}
  1709. X
  1710. X/*
  1711. X * convert an ether_addr to an ax25_addr
  1712. X */
  1713. Xax_ether2ax(ethp, axhp)
  1714. Xstruct ether_addr *ethp;
  1715. Xu_char *axhp;
  1716. X{
  1717. X    u_char c;
  1718. X    int i;
  1719. X
  1720. X#ifdef DEBUG2
  1721. X    for(i=0; i<sizeof(struct ether_addr)-1; i++)
  1722. X        printf("%2x:", ethp->ether_addr_octet[i]);
  1723. X    printf("%2x == ", ethp->ether_addr_octet[5]);
  1724. X#endif
  1725. X
  1726. X    if( !bcmp((caddr_t)ethp, (caddr_t)ðernulladdr,
  1727. X        sizeof(struct ether_addr))) {
  1728. X#ifdef DEBUG2
  1729. X        printf("nothing\n");
  1730. X#endif
  1731. X        for(i=0; i<7; i++)
  1732. X            axhp[i] = (u_char)0;
  1733. X        return;
  1734. X    }
  1735. X    if( !bcmp((caddr_t)ethp, (caddr_t)ðerbroadcastaddr,
  1736. X        sizeof(struct ether_addr))) {
  1737. X        bcopy((caddr_t)ax25broadcastaddr, (caddr_t)axhp,
  1738. X            sizeof(ax25broadcastaddr));
  1739. X        goto done;
  1740. X    }
  1741. X    c = ethp->ether_addr_octet[0];
  1742. X    if(c != 0x99) {
  1743. X#ifdef DEBUG2
  1744. X        printf("[NO MAPPING]\n");
  1745. X#endif
  1746. X        for(i=0; i<7; i++)
  1747. X            axhp[i] = (u_char)0;
  1748. X        return;
  1749. X    }
  1750. X    c =  (ethp->ether_addr_octet[1] >> 2) & 0x3f;
  1751. X    axhp[0] = (u_char)((c + ' ') << 1);
  1752. X    c =  (ethp->ether_addr_octet[1] << 4) & 0x30;
  1753. X    c |= (ethp->ether_addr_octet[2] >> 4) & 0x0f;
  1754. X    axhp[1] = (u_char)((c + ' ') << 1);
  1755. X    c =  (ethp->ether_addr_octet[2] << 2) & 0x3c;
  1756. X    c |= (ethp->ether_addr_octet[3] >> 6) & 0x03;
  1757. X    axhp[2] = (u_char)((c + ' ') << 1);
  1758. X    c =  (ethp->ether_addr_octet[3]     ) & 0x3f;
  1759. X    axhp[3] = (u_char)((c + ' ') << 1);
  1760. X    c =  (ethp->ether_addr_octet[4] >> 2) & 0x3f;
  1761. X    axhp[4] = (u_char)((c + ' ') << 1);
  1762. X    c =  (ethp->ether_addr_octet[4] << 4) & 0x30;
  1763. X    c |= (ethp->ether_addr_octet[5] >> 4) & 0x0f;
  1764. X    axhp[5] = (u_char)((c + ' ') << 1);
  1765. X    c =  (ethp->ether_addr_octet[5]     ) & 0x0f;
  1766. X    axhp[6] = (u_char)((c + '0') << 1);
  1767. X
  1768. Xdone:
  1769. X#ifdef DEBUG2
  1770. X    for(i=0; i<6; i++)
  1771. X        printf("%2x.", axhp[i]);
  1772. X    printf("%2x '", axhp[6]);
  1773. X
  1774. X    for(i=0; i<6; i++)
  1775. X        printf("%c", (axhp[i] >> 1) & 0x7f );
  1776. X    printf("-%c'\n", ((axhp[6] & 0x7f) >> 1) & 0x7f );
  1777. X#endif
  1778. X    return;
  1779. X}
  1780. X
  1781. Xprint_ax25addr(axhp)
  1782. Xu_char *axhp;
  1783. X{
  1784. X    int i;
  1785. X
  1786. X#ifdef DEBUG2
  1787. X    for(i=0; i<6; i++)
  1788. X        printf("%2x.", axhp[i]);
  1789. X    printf("%2x", axhp[6]);
  1790. X#endif
  1791. X
  1792. X    printf("(");
  1793. X    for(i=0; i<6; i++)
  1794. X        printf("%c", (axhp[i]>>1) & 0x7f );
  1795. X    printf("-%c)", ((axhp[6]&0x7f)>>1) & 0x7f );
  1796. X}
  1797. X
  1798. Xax25_arpdebug(m0)
  1799. Xstruct mbuf *m0;
  1800. X{
  1801. X    struct mbuf *m;
  1802. X    int len, n;
  1803. X    u_char *cp;
  1804. X
  1805. X    len = 0;
  1806. X    for(m=m0; m; m=m->m_next) {
  1807. X        printf("*");
  1808. X        cp = mtod(m, u_char *);
  1809. X        n = m->m_len;
  1810. X        while(n-->0) {
  1811. X            if( !(len++ % 16) )
  1812. X                printf("\n\t");
  1813. X            printf("%2x ", *cp++);
  1814. X        }
  1815. X    }
  1816. X    if( len % 16 )
  1817. X        printf("\n");
  1818. X}
  1819. X
  1820. X
  1821. X#endif    /* !(NAX > 0) */
  1822. X
  1823. END_OF_FILE
  1824. if test 23598 -ne `wc -c <'tty_ax.c'`; then
  1825.     echo shar: \"'tty_ax.c'\" unpacked with wrong size!
  1826. fi
  1827. # end of 'tty_ax.c'
  1828. fi
  1829. echo shar: End of shell archive.
  1830. exit 0
  1831.